package com.easychat.service.impl;

import com.easychat.common.LeaseException;
import com.easychat.common.PageResult;
import com.easychat.dto.MessageSendDto;
import com.easychat.dto.TokenUserInfoDto;
import com.easychat.entity.ChatSessionUser;
import com.easychat.entity.UserContact;
import com.easychat.entity.UserInfo;
import com.easychat.entity.config.AppConfig;
import com.easychat.entity.constants.Constants;
import com.easychat.entity.query.UserContactQuery;
import com.easychat.enums.ExceptionCodeEnum;
import com.easychat.enums.MessageTypeEnum;
import com.easychat.enums.UserContactTypeEnum;
import com.easychat.enums.UserStatusEnum;
import com.easychat.mappers.ChatSessionUserDao;
import com.easychat.mappers.UserContactDao;
import com.easychat.mappers.UserInfoDao;
import com.easychat.redis.RedisComponent;
import com.easychat.service.UserInfoService;
import com.easychat.websocket.MessageHandler;
import com.github.pagehelper.PageHelper;
import org.apache.catalina.User;
import org.springframework.stereotype.Service;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.List;

/**
 * 用户消息表(UserInfo)表服务实现类
 *
 * @author makejava
 * @since 2024-10-01 17:31:43
 */
@Service("userInfoService")
public class UserInfoServiceImpl implements UserInfoService {
    @Resource
    private UserInfoDao userInfoDao;

    @Resource
    private AppConfig appConfig;
    @Resource
    private ChatSessionUserDao chatSessionUserDao;
    @Resource
    private MessageHandler messageHandler;
    @Resource
    private UserContactDao userContactDao;
    @Resource
    private RedisComponent redisComponent;
    /**
     * 通过ID查询单条数据
     *
     * @param userId 主键
     * @return 实例对象
     */
    @Override
    public UserInfo queryById(String userId) {
        return this.userInfoDao.queryById(userId);
    }

    /**
     * 分页查询
     *
     * @param userInfo    筛选条件
     * @param pageRequest 分页对象
     * @return 查询结果
     */
    @Override
    public PageResult queryByPage(UserInfo userInfo, PageRequest pageRequest) {
        long total = this.userInfoDao.count(userInfo);
        PageHelper.startPage(pageRequest.getPageNumber(),pageRequest.getPageSize());
        PageHelper.orderBy("create_time desc");
        List<UserInfo> userInfoList = userInfoDao.queryAllByLimit(userInfo);
        PageResult pageResult = new PageResult(total, userInfoList);
        return pageResult;
    }

    /**
     * 新增数据
     *
     * @param userInfo 实例对象
     * @return 实例对象
     */
    @Override
    public boolean insert(UserInfo userInfo) {
        int insert = userInfoDao.insert(userInfo);
        if(insert == 1){
            return true;
        }
        return false;
    }

    /**
     * 修改数据
     *
     * @param userInfo 实例对象
     * @return 实例对象
     */
    @Override
    public boolean update(UserInfo userInfo) {
        int update = userInfoDao.update(userInfo);
        if(update == 1){
            return true;
        }
        return false;
    }

    /**
     * 根据email查询对象
     * @param email
     * @return
     */
    @Override
    public UserInfo getUserInfoByEmail(String email) {
         UserInfo userInfo = userInfoDao.queryByEmail(email);
        return userInfo;
    }

    /**
     * 通过主键删除数据
     *
     * @param userId 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(String userId) {
        return this.userInfoDao.deleteById(userId) > 0;
    }

    /**
     * 根据userId模糊分页查询
     * @param userId
     * @param pageRequest
     * @return
     */
    @Override
    public PageResult queryByFuzzyUserIdPage(String userId, PageRequest pageRequest) {
        PageHelper.startPage(pageRequest.getPageNumber(),pageRequest.getPageSize());
        List<UserInfo>  userInfoList = userInfoDao.queryByFuzzyUserId(userId);
        long total = userInfoList.size();
        PageResult pageResult = new PageResult(total, userInfoList);
        return pageResult;
    }

    @Override
    public UserInfo getUserInfoByUserId(String contactId) {
        UserInfo userInfo = userInfoDao.queryById(contactId);
        return userInfo;
    }

    @Override
    public void updateUserInfo(UserInfo userInfo, MultipartFile avatarFile, MultipartFile avatarCover) throws IOException {
            if(avatarFile != null){
                String baseFolder = appConfig.getProjectFolder() + Constants.FILE_FOLDER_FILE;
                File targetFileFolder = new File(baseFolder + Constants.FILE_FOLDER_AVATAR_NAME);
                if(targetFileFolder == null){
                    targetFileFolder.mkdirs();
                }
                String filePath = targetFileFolder.getPath() + "/" + userInfo.getUserId() + Constants.IMAGE_SUFFIX;
                avatarFile.transferTo(new File(filePath));
                avatarCover.transferTo(new File(filePath+Constants.COVER_IMAGE_SUFFIX));
            }
            UserInfo dbInfo = userInfoDao.queryById(userInfo.getUserId());
            userInfoDao.updateByUserId(userInfo,userInfo.getUserId());
            String contactNameUpdate = null;
            if(!dbInfo.getNickName().equals(userInfo.getNickName())){
                contactNameUpdate = userInfo.getNickName();
            }
            //更新会话信息中的昵称信息
            if(contactNameUpdate == null){
                return;
            }

            //更新token中的昵称
            TokenUserInfoDto tokenUserInfoDto = redisComponent.getTokenUserInfoByUserId(userInfo.getUserId());
            tokenUserInfoDto.setNickName(contactNameUpdate);
            redisComponent.saveTokenUserInfoDto(tokenUserInfoDto);

        ChatSessionUser chatSessionUser = new ChatSessionUser();
        chatSessionUser.setContactName(contactNameUpdate);
        chatSessionUser.setContactId(userInfo.getUserId());
        chatSessionUserDao.update(chatSessionUser);

        MessageSendDto messageSendDto = new MessageSendDto();
        messageSendDto.setContactType(UserContactTypeEnum.USER.getType());
        messageSendDto.setExtendData(contactNameUpdate);

        UserContactQuery userContactQuery = new UserContactQuery();
        userContactQuery.setUserId(userInfo.getUserId());
        userContactQuery.setContactType(UserContactTypeEnum.USER.getType());
        userContactQuery.setStatus(1);
        List<UserContact> contactIdList = userContactDao.selectByParamQuery(userContactQuery);
        if(contactIdList==null || contactIdList.size()<1){
            return;
        }
        for (UserContact userContact:contactIdList){
            messageSendDto.setContactType(UserContactTypeEnum.USER.getType());
            messageSendDto.setContactId(userContact.getContactId());
            messageSendDto.setMessageType(MessageTypeEnum.CONTACT_NAME_UPDATE.getType());
            messageSendDto.setSendUserId(userInfo.getUserId());
            messageSendDto.setSendUserNickName(contactNameUpdate);
            messageSendDto.setExtendData(contactNameUpdate);
            messageHandler.sendMessage(messageSendDto);
        }

    }

    @Override
    public void updateUserInfoByUserId(UserInfo userInfo,String userId) {
        userInfoDao.updateByUserId(userInfo,userId);
    }

    @Override
    public void updateUserStatus(Integer status, String userId) {
        UserStatusEnum userStatusEnum = UserStatusEnum.getByStatus(status);
        if(userStatusEnum== null){
            throw new LeaseException(ExceptionCodeEnum.ERROR_REQUEST);
        }
        UserInfo userInfo = new UserInfo();
        userInfo.setStatus(status);
        userInfoDao.updateByUserId(userInfo,userId);

    }

    @Override
    public void forceOfLine(String userId) {
        // 强制下线
        MessageSendDto messageSendDto = new MessageSendDto();
        messageSendDto.setContactType(UserContactTypeEnum.USER.getType());
        messageSendDto.setMessageType(MessageTypeEnum.FORCE_OFF_LINE.getType());
        messageSendDto.setContactId(userId);
        messageHandler.sendMessage(messageSendDto);

    }
}
